﻿//
// $HeadURL: http://codeka-memcache.googlecode.com/svn/trunk/Codeka.Memcache/ServerPool.cs $
// $Revision: 7 $
// $Author: dean.codeka $     $Date: 2010-02-20 12:24:59 +0000 (Sat, 20 Feb 2010) $
//
// Copyright © 2009-2010 Dean Harding, all rights reserved.
//

using System.Collections.Generic;
using System.Linq;
using Codeka.Memcache.Config;

namespace Codeka.Memcache
{
    /// <summary>
    /// Server pool class contains the list of servers that we have configured
    /// and provides the initial hashing functions to select a server.
    /// </summary>
    public class ServerPool
    {
        private IMemcacheConfiguration config;
        private ConsistentHasher hasher;
        private IDictionary<ServerConfig, ServerConnection> servers;

        /// <summary>
        /// Constructs a new <see cref="ServerPool"/> using the given <see cref="IMemcacheConfiguration"/>
        /// as the configuration settings.
        /// </summary>
        public ServerPool(IMemcacheConfiguration config)
        {
            this.config = config;

            servers = new SortedDictionary<ServerConfig, ServerConnection>();
            foreach (var svrConfig in config.GetServers())
            {
                servers.Add(svrConfig, new ServerConnection(svrConfig));
            }

            hasher = new ConsistentHasher(servers.Keys);
        }

        /// <summary>
        /// Gets an <see cref="IEnumerable{T}"/> collection of all the <see cref="ServerConnection"/>s
        /// we're currently 
        /// </summary>
        public IEnumerable<ServerConnection> GetServers()
        {
            // we create a copy so that it doesn't matter if a server goes down
            // in the meantime, etc.
            var list = new List<ServerConnection>(from svr in servers.Values select svr);
            return list;
        }

        /// <summary>
        /// Gets the <see cref="ServerConnection"/> that corresponds to the given
        /// <see cref="ServerConfig"/>.
        /// </summary>
        /// <param name="svrConfig">The <see cref="ServerConfig"/> we want the connection
        /// for.</param>
        public ServerConnection GetServer(ServerConfig svrConfig)
        {
            return servers[svrConfig];
        }

        /// <summary>
        /// Gets the <see cref="ServerConnection"/> for the server that corresponds to
        /// the given <c>key</c>.
        /// </summary>
        /// <param name="key">The key to fetch.</param>
        /// <returns>The <see cref="ServerConnection"/> corresponding to that key.</returns>
        public ServerConnection GetServer(string key)
        {
            var svrConfig = hasher.GetServer(key);
            return GetServer(svrConfig);
        }
    }
}
